#include "taskitem.h"
#include "ndb.h"


configFile *taskItem::configfile = nullptr;
configInfo *taskItem::config = nullptr;

QMap<int, taskItem*> taskItem::all_tasks;

//configFile *taskItem::configfile = nullptr;
//configInfo *taskItem::config = nullptr;

//int taskItem::eachTomato = 12;
//int taskItem::eachTomato_rest = 6;
//int taskItem::globalTomatoToday = 0;


std::array<QString,  5> taskItem::sortArray{"重要紧急","重要不紧急","不重要不紧急","不重要紧急", "休息"};
QMap<QString, int> taskItem::sort2Int{{"重要紧急",0}, {"重要不紧急",1}, {"不重要不紧急",2}, {"不重要紧急",3},{"不重要紧急",4}};

taskItem::taskItem(int id, QString taskName, int sort, unsigned int eachDayTomatoes,int tomatoesTotal , unsigned int todayAchieveTomato, unsigned int tomatoesAchieveTotal,QDateTime today,int days, QDateTime startDate, QString describe, QObject *parent):
    QObject(parent),
    m_currentSubTaskId(-1)
{
    this->m_id = id;
    this->m_taskName = taskName;
    this->m_sort = sort;
    this->m_eachDayTomatoes = eachDayTomatoes;
    this->m_tomatoesTotal = tomatoesTotal;
    this->m_today = today;
    this->m_days = days;
    this->m_startDate = startDate;
    this->m_tomatoesAchieveTotal = tomatoesAchieveTotal;
    if (describe.isEmpty())
        m_describe = config->m_defaultDescribe;
    else
        this->m_describe = describe;


    if (isToday()){
        this->m_todayAchieveTomato = todayAchieveTomato;
    } else {
        this->m_todayAchieveTomato = 0;
    }

}

taskItem::taskItem(QString taskName, int sort, unsigned int eachDayTomatoes, int tomatoesTotal, int days, QString describe, QObject *parent):
     QObject(parent),
     m_currentSubTaskId(-1)
{
    this->m_id = -1;
    this->m_taskName = taskName;
    this->m_sort = sort;
    this->m_eachDayTomatoes = eachDayTomatoes;
    this->m_tomatoesTotal = tomatoesTotal;
    this->m_today = QDateTime::currentDateTime();
    this->m_days = days;
    this->m_startDate = QDateTime::currentDateTime();
    this->m_todayAchieveTomato = 0;
    this->m_tomatoesAchieveTotal = 0;
    if (describe.isEmpty())
        m_describe = config->m_defaultDescribe;
    else
        this->m_describe = describe;




}

taskItem::taskItem(const taskItem &t):
   QSharedData(t)

   , m_id(t.m_id)
   , m_taskName(t.m_taskName)
   , m_sort(t.m_sort)
   , m_eachDayTomatoes(t.m_eachDayTomatoes)
   , m_tomatoesTotal(t.m_tomatoesTotal)
   , m_today(t.m_today)
   , m_days(t.m_days)
   , m_startDate(t.m_startDate)
   , m_todayAchieveTomato(t.m_todayAchieveTomato)
   , m_tomatoesAchieveTotal(t.m_tomatoesAchieveTotal)
   , m_currentSubTaskId(t.m_currentSubTaskId)
   , m_describe(t.m_describe)
   , m_subTaskMap(t.m_subTaskMap)
{

}



taskItem::taskItem(QObject *parent):
     QObject(parent),
     m_currentSubTaskId(-1)
{
}


void taskItem::loadSubTask()
{
    m_subTaskMap.clear();
    const QString sql = "SELECT id,name, tomato, achieve, describe FROM subtask WHERE taskid=:taskid;";
    Ndb::query.prepare(sql);
    Ndb::query.bindValue(":taskid", m_id);
    if (!Ndb::query.exec())
    {
        qDebug() << "task " << m_taskName << "get subtask error " << Ndb::query.lastError();
        return ;
    }

    while(Ndb::query.next())
    {
        subTask subtask;
        subtask.id = Ndb::query.value("id").toInt();
        subtask.name = Ndb::query.value("name").toString();
        subtask.tomato =  Ndb::query.value("tomato").toInt();
        subtask.achieve = Ndb::query.value("achieve").toInt();
        subtask.describe = Ndb::query.value("describe").toString();
        m_subTaskMap.insert(subtask.id, subtask);
    }


}

void taskItem::addSubTask(int id, const QString &name, int tomatoes)
{

    if (!m_subTaskMap.contains(id))
    {
        subTask subtask;
        subtask.id = id;
        subtask.name = name;
        subtask.tomato =  tomatoes;
        subtask.achieve = 0;
        subtask.describe = "";

        this->m_subTaskMap.insert(subtask.id, subtask);


        if (m_subTaskMap.size() == 1 && id >= 0) this->m_currentSubTaskId = id;
    }

}



void taskItem::addSubTask(const subTask &subtask)
{

    if (!m_subTaskMap.contains(subtask.id))
    {
        m_subTaskMap.insert(subtask.id, subtask);

        if (m_subTaskMap.size() == 1 && subtask.id >= 0) m_currentSubTaskId = subtask.id;
    } else
    {
        m_subTaskMap[subtask.id] = subtask;
    }

}

void taskItem::copy(const taskItem &t)
{
    this->m_id = t.m_id;
    this->m_taskName = t.m_taskName;
    this->m_sort = t.m_sort;
    this->m_eachDayTomatoes = t.m_eachDayTomatoes;
    this->m_tomatoesTotal = t.m_tomatoesTotal;
    this->m_today = t.m_today;
    this->m_days = t.m_days;
    this->m_startDate = t.m_startDate;
    this->m_todayAchieveTomato = t.m_todayAchieveTomato;
    this->m_tomatoesAchieveTotal = t.m_tomatoesAchieveTotal;
    this->m_currentSubTaskId = t.m_currentSubTaskId;
    this->m_describe = t.m_describe;

    this->m_subTaskMap = t.m_subTaskMap;
}



bool taskItem::deleteSubTask(int subTaskId)
{

    if (m_subTaskMap.contains(subTaskId))
    {
        Ndb::deleteSubTask(subTaskId);
        m_subTaskMap.remove(subTaskId);
        return true;
    }
    return false;

}



bool taskItem::isToday(){
    QDateTime current_date_time =QDateTime::currentDateTime();
    QDate current_date =current_date_time.date();

    return m_today.date() == current_date;

}

int taskItem::todayAchieveTomatoes(){

    if (isToday()){
        return this->m_todayAchieveTomato;
    } else {
        this->m_todayAchieveTomato = 0;
        return 0;
    }
}

int taskItem::remainDay()
{
    if (m_days >= 0)
        return  (int)ceil((m_tomatoesTotal-m_tomatoesAchieveTotal)/(double)m_eachDayTomatoes);
    else
        return m_days;
}

QString taskItem::remainDay_str()
{
    if (m_days >= 0)
        return  QString("%1").arg((int)ceil((m_tomatoesTotal-m_tomatoesAchieveTotal)/(double)m_eachDayTomatoes));
    else
        return "每天";
}


void taskItem::addTodayTime(int tomatoCount){
    if (!isToday()) m_todayAchieveTomato = 0;
    m_today =QDateTime::currentDateTime();
    m_todayAchieveTomato += tomatoCount;
    m_tomatoesAchieveTotal += tomatoCount;

    configfile->m_config.m_tomatoAchieveToday += tomatoCount;

    qDebug() << "currentSubTaskName " << m_currentSubTaskId;
    if (m_currentSubTaskId >= 0) m_subTaskMap[m_currentSubTaskId].achieve += tomatoCount;
    updatedb(Ndb::query);
    configfile->save();
    emit taskItemChange(*this);
}

int taskItem::alterSort2Int(const QString &text)
{
    return taskItem::sort2Int.value(text);
}

void taskItem::insertdb(QSqlQuery &query)
{
    QString sql;

    sql = QString("insert into %1 (taskName,sort,eachDayTomatoes,tomatoesTotal,tomatoesAchieveTotal,days,describe) values(:taskName,:sort,:eachDayTomatoes,:tomatoesTotal,:tomatoesAchieveTotal,:days,:describe)").arg(Ndb::tableName);

    query.prepare(sql);
    query.bindValue(":taskName", m_taskName);
    query.bindValue(":sort",m_sort);
    query.bindValue(":eachDayTomatoes", m_eachDayTomatoes);
    query.bindValue(":tomatoesTotal", m_tomatoesTotal);
    query.bindValue(":tomatoesAchieveTotal", m_tomatoesAchieveTotal);
    query.bindValue(":describe", m_describe);

    query.bindValue(":days", m_days);



    if (!query.exec()){
        qDebug() << "new task " << m_taskName << " insert error " << query.lastError()<< "\n" << query.lastQuery();
    }

    this->m_id = Ndb::getLastInsertId(Ndb::tableName);
    this->m_today = QDateTime::currentDateTime();
    this->m_startDate = QDateTime::currentDateTime();

    Ndb::addSubTasks(m_id, m_subTaskMap);


}


void taskItem::updatedb(QSqlQuery &query){
    if (m_id == -1)
    {
        qDebug() << "can not update db with id = " << m_id;
        return;
    }

    QString sql;
    sql = QString("update %1 set taskName=:taskName, sort=:sort, eachDayTomatoes=:eachDayTomatoes, tomatoesTotal=:tomatoesTotal,tomatoesAchieveTotal=:tomatoesAchieveTotal, today=:today, days=:days ,startDate=:startDate, todayAchieveTomato=:todayAchieveTomato, describe=:describe where id=:id").arg(Ndb::tableName);
    query.prepare(sql);
    query.bindValue(":taskName", m_taskName);
    query.bindValue(":sort", m_sort);
    query.bindValue(":eachDayTomatoes", m_eachDayTomatoes);
    query.bindValue(":tomatoesTotal", m_tomatoesTotal);
    query.bindValue(":tomatoesAchieveTotal", m_tomatoesAchieveTotal);
    query.bindValue(":today", m_today.toString(Ndb::DateFormat));
    query.bindValue(":days", m_days);
    query.bindValue(":startDate", m_startDate.toString(Ndb::DateFormat));
    query.bindValue(":todayAchieveTomato", m_todayAchieveTomato);
    query.bindValue(":describe", m_describe);
    query.bindValue(":id", m_id);


    if (!query.exec()){
        qDebug() << m_id << " " << m_taskName << " update error " << query.lastError();
    }
    qDebug() << "update sql " << query.lastQuery();

    Ndb::addSubTasks(m_id, m_subTaskMap);
    loadSubTask();


}
